package com.zero.java.base.stream;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author Lenovo
 *
 */
public class IntStreamAPI {
	
	private static final String file_name = "cfg/words.txt";

	public static void main(String[] args) throws IOException {

		IntStream intStream = IntStream.generate(() -> (int)(Math.random() * 100));
		show("intStream",intStream);
		
		IntStream rangeNum = IntStream.range(0, 100);
		show("rangeNum", rangeNum);
		
		IntStream rangeNum02 = IntStream.rangeClosed(10, 100);
		show("rangeNum02",rangeNum02);
		
		String contents = new String(Files.readAllBytes(Paths.get(file_name)),StandardCharsets.UTF_8);
		Stream<String> words = Stream.of(contents.split("\\PL+"));
		
		//mapToInt:转化为基本数据类型,计算每一个单词的长度
		IntStream wordsLenght = words.mapToInt(String :: length);
		show("wordsLenght", wordsLenght);
		
		//显示编码
		/*String sentence = "\uD835\uDD46 is the set of octonions";
		System.out.println(sentence);
		IntStream codes = sentence.codePoints();
		String code = codes.mapToObj(c -> String.format("%X", c)).collect(Collectors.joining(","));
		System.out.println(code);*/
		
		//boxed:将基本类型流转化为对象流
		Stream<Integer> integers = IntStream.range(0, 100).boxed();
		//toArray返回一个基本类型数组
		Object[] arrayNum = integers.limit(10).toArray();
		for (int i = 0; i < arrayNum.length; i++) {
			System.out.println("遍历数组:"+arrayNum[i]);
		}
		//将对象流转为基本数据流
		integers = IntStream.range(0, 100).boxed();
		IntStream mapToIntResult = integers.mapToInt(Integer :: intValue);
		show("mapToIntResult", mapToIntResult);
		
		//sum:产生当前流中元素的总和
		int sumResult = IntStream.range(0, 100).sum();
		System.out.println("sumResult:"+sumResult);
		
		//average:产生当前流中元素的平均值
		OptionalDouble averageResult = IntStream.range(0, 5).average();
		System.out.println("averageResult:"+averageResult);
		double asDoubleResult = averageResult.getAsDouble();
		System.out.println("asDoubleResult:"+asDoubleResult);
		
		//max,min
		OptionalInt maxOptional = IntStream.range(0, 5).max();
		int asIntResult = maxOptional.getAsInt();
		System.out.println("asIntResult:"+asIntResult);
		
		OptionalInt minOptional = IntStream.range(0, 5).min();
		int asIntResult02 = minOptional.getAsInt();
		System.out.println("asIntResult02:"+asIntResult02);
		
		//summaryStatistics[count,average,max,min]
		IntSummaryStatistics summaryStatistics = IntStream.range(0, 5).summaryStatistics();
		System.out.println("summaryStatistics:"+summaryStatistics);
		long count = summaryStatistics.getCount();
		System.out.println("count:"+count);
		double average = summaryStatistics.getAverage();
		System.out.println("average:"+average);
		int max = summaryStatistics.getMax();
		System.out.println("max:"+max);
		int min = summaryStatistics.getMin();
		System.out.println("min:"+min);
		
		//Random[ints]
		Random random = new Random();
		IntStream ints = random.ints();
		show("ints", ints);
		IntStream ints2 = random.ints(5);
		show("ints2", ints2);
		IntStream ints3 = random.ints(0, 5);
		show("ints3", ints3);
		
		//OptionalInt[of]
		OptionalInt optionalInt = OptionalInt.of(10);
		int asInt = optionalInt.getAsInt();
		System.out.println("asInt:"+asInt);
		
		String s = "superman";
		String orElse = Optional.ofNullable(s).orElse("no value");
		System.out.println("orElse:"+orElse);
		
		Optional<String> findFirst = words.filter(as -> as.length()>10).findFirst();
		Optional<String> orElseGet = Optional.ofNullable(findFirst).orElseGet(null);
		System.out.println("orElseGet:"+orElseGet);
	}

	public static void show(String title, IntStream intStream) {
		final int SIZE = 10;
		int[] firstElements = intStream.limit(SIZE + 1).toArray();
		System.out.print(title + ":");
		for (int i = 0; i < firstElements.length; i++) {
			if (i > 0) {
				System.out.print(",");
			}
			if (i < SIZE) {
				System.out.print(firstElements[i]);
			} else {
				System.out.print(".....");
			}
		}
		System.out.println();
	}

}
